package com.example.infrastructure.framework.exception;

import com.example.common.constant.HttpStatus;
import com.example.common.core.domain.Result;
import com.example.common.enums.ErrorType;
import com.example.common.exception.PermissionException;
import com.example.common.exception.ServiceException;
import com.example.common.exception.file.FileSizeLimitExceededException;
import com.example.common.utils.ServletUtils;
import com.example.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;

import javax.naming.SizeLimitExceededException;
import javax.servlet.http.HttpServletRequest;


/**
 * 全局异常拦截捕获
 * 用@ControllerAdvice注解可以将对于控制器的全局配置放在同一个位置
 * 配合@ExceptionHandler使用可进行全局异常处理，当将异常抛到controller时,可以对异常进行统一处理,规定返回的json格式或是跳转到一个错误页面
 * 此处返回值须与controller中保持一致
 */

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {


    /**
     * 文件大小超过最大值异常
     * */
    @ResponseBody
    @ExceptionHandler(value = MultipartException.class)
    public Result<?> multipartExceptionHandler(MaxUploadSizeExceededException e){

        Throwable throwable = e.getCause();
        log.error("上传文件大小限制异常：{}", e.getMessage());


        Result<?> result = null;

        if (throwable.getCause() instanceof FileSizeLimitExceededException){

            result =  Result.error(-1,"文件大小超过限制，请上传100M内的文件");
        }

        if (throwable.getCause() instanceof SizeLimitExceededException){

            result =  Result.error(-1,"大小超过限制！");
        }

        return result;

    }


    /**
     * 权限认证异常
     */

    @ExceptionHandler(PermissionException.class)
    @ResponseBody //为了返回数据
    public Result<?> error(PermissionException pe) {
        log.warn("权限认证失败：{}",pe.getMessage());
        return Result.error( ErrorType.INSUFFICIENT_PERMISSION.ordinal(),"当前用户不具备该权限，请联系管理员！");
    }


    /**
     * 业务异常
     */
    @ExceptionHandler(ServiceException.class)
    @ResponseBody
    public Result<?> handleServiceException(ServiceException e, HttpServletRequest request)
    {
        log.error(e.getMessage(), e);
        Integer code = e.getCode();
        return Result.error( StringUtils.isNotNull(code) ? code: HttpStatus.ERROR,e.getMessage());
    }


    /**
     * 断言异常
     */
    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseBody
    public Result<?> illegalArgumentException(IllegalArgumentException e){
        log.error("断言异常：{}（请求来源：{}）", e.getMessage(), ServletUtils.getRequest().getRequestURI());
        return Result.error( HttpStatus.ERROR,e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result<?> handleException(Exception e){
        log.error("业务系统异常：{}（请求来源：{}）,", e, ServletUtils.getRequest().getRequestURI());
        return Result.error( HttpStatus.ERROR,e.getMessage());
    }


}
